package gui.dialog;

import gui.extra.*;
import lib.control.VideoPatterns;
import net.miginfocom.swing.MigLayout;
import settings.SettingsControl;
import settings.model.LibrarySettings;
import settings.model.SettingsExcludeItem;
import settings.model.SettingsExcludeType;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PreferenceDialog extends JBierSubDialog {

    /**
     *
     */
    private static final long serialVersionUID = -5730220264781738564L;
    private final JPanel contentPanel = new JPanel();
    private JCheckBox chkOnlyFound, chkAlwaysConfirm, chkExactMatch;
    private SettingsControl settingsCtrl;
    private EpisodeLibraryPanel pnlEpisodeLibrary;
    private JListWithImages excludeList;
    private JCheckBox chkStopOnSearchError;
    private JCheckBox chkAutomaticDownloadSelection;
    private JTable table;
    private JCheckBox chkNoRuleMatchTakeFirst;
    private MovieLibraryPanel pnlMovieLibrary;
    private JTextField txtProxyHost;
    private JTextField txtProxyPort;
    private JCheckBox chkProxyserverGebruiken;
	private JListWithImages defaultIncomingFoldersList;

    /**
     * Create the dialog.
     */
    public PreferenceDialog(JFrame frame, final SettingsControl settingsCtrl) {
        super(frame, "Voorkeuren", true);
        this.settingsCtrl = settingsCtrl;
        initialize();
        initializeTable();
        setPreferenceSettings();
        repaint();
    }

    private void initializeTable() {
        DefaultTableModel model = (DefaultTableModel) table.getModel();

        // Add some columns
        model.addColumn("Regel Nummer");
        model.addColumn("Kwaliteit");
    }

    private void addRuleRow(String q) {
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        model.addRow(new Object[]{model.getRowCount() + 1, q});
        // These are the combobox values
        List<String> both = new ArrayList<String>(1 
        		+ VideoPatterns.QUALITYKEYWORDS.length
        		+ VideoPatterns.GROUPEDQUALITYKEYWORDS.length);
        Collections.addAll(both, "Selecteer...");
        //additional grouped keywords
        Collections.addAll(both, VideoPatterns.GROUPEDQUALITYKEYWORDS);
        //keywords
        Collections.addAll(both, VideoPatterns.QUALITYKEYWORDS);
        String[] values = both.toArray(new String[]{});

        // Set the combobox editor on the 1st visible column
        int vColIndex = 1;
        TableColumn col = table.getColumnModel().getColumn(vColIndex);
        col.setCellEditor(new MyComboBoxEditor(values));
        // If the cell should appear like a combobox in its
        // non-editing state, also set the combobox renderer
        col.setCellRenderer(new MyComboBoxRenderer(values));
    }

    private void removeRuleRow() {
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        if (table.getSelectedRow() >= 0) {
            model.removeRow(table.getSelectedRow());
        }

    }

    private void initialize() {
        setResizable(false);
        setModalityType(ModalityType.APPLICATION_MODAL);
        setBounds(100, 100, 615, 650);
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
        contentPanel.setLayout(new BorderLayout(0, 0));
        {
            JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
            tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
            contentPanel.add(tabbedPane);
            {
                JPanel pnlGeneral = new JPanel();
                tabbedPane.addTab("Algmeen", null, pnlGeneral, null);
                pnlGeneral
                        .setLayout(new MigLayout("", "[127px,grow][grow][grow]", "[23px][grow][][][grow,center][grow]"));
                {
                    JLabel lblDefaultIncomingFolder = new JLabel(
                            "Standaard inkomende map");
                    pnlGeneral.add(lblDefaultIncomingFolder,
                            "cell 0 0,alignx left,aligny center");
                }
                {
                    JButton btnBrowse = new JButton("map toevoegen");
                    btnBrowse.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent arg0) {
                            File path = MemoryFolderChooser.getInstance().selectDirectory(getContentPane(), "Selecteer map");
                            if (defaultIncomingFoldersList.getModel().getSize() == 0 ){
                            	defaultIncomingFoldersList.addItem(SettingsExcludeType.FOLDER, path.getAbsolutePath());
                            }else{
                            	boolean exists = false;
	                            for (int i = 0; i < defaultIncomingFoldersList.getModel().getSize(); i++){
	            	                if (defaultIncomingFoldersList.getDescription(i).equals(path.getAbsolutePath())){
	                                    exists = true;
	                                }
	                            }
	                            if (!exists){
	                            	defaultIncomingFoldersList.addItem(SettingsExcludeType.FOLDER, path.getAbsolutePath());
	                            }
                            }
                        }
                    });
                    pnlGeneral
                            .add(btnBrowse, "cell 1 0,alignx left,aligny top");
                }
                {
                	JButton button = new JButton("map verwijderen");
                	button.addActionListener(new ActionListener() {
                		public void actionPerformed(ActionEvent arg0) {
                			DefaultListModel<JPanel> model = (DefaultListModel<JPanel>) defaultIncomingFoldersList.getModel();
                	        int selected = defaultIncomingFoldersList.getSelectedIndex();
                	        if (model.size() > 0 && selected >= 0) {
                	            model.removeElementAt(selected);
                	        }
                		}
                	});
                	pnlGeneral.add(button, "cell 2 0");
                }
                {
                	JScrollPane scrollPane = new JScrollPane();
                	pnlGeneral.add(scrollPane, "cell 1 1 2 1,grow");
                	{
                		defaultIncomingFoldersList = new JListWithImages();
                		scrollPane.setViewportView(defaultIncomingFoldersList);
                	}
                }
                {
                    JLabel lblUitsluitLijst = new JLabel("Uitsluit lijst");
                    pnlGeneral.add(lblUitsluitLijst,
                            "cell 0 2,alignx right,gaptop 10");
                }
                {
                    JButton btnAddUitsluitMap = new JButton("map toevoegen");
                    btnAddUitsluitMap.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent arg0) {
                            addExcludeItem(SettingsExcludeType.FOLDER);
                        }
                    });
                    pnlGeneral.add(btnAddUitsluitMap,
                            "cell 1 2,alignx center,gaptop 10");
                }
                {
                    JButton btnVerwijderUitsluitMap = new JButton(
                            "item verwijderen");
                    btnVerwijderUitsluitMap
                            .addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent arg0) {
                                    removeExcludeItem();
                                }
                            });
                    pnlGeneral.add(btnVerwijderUitsluitMap,
                            "cell 2 2,alignx center,gaptop 10");
                }
                {
                    JButton btnAddUitsluitRegex = new JButton("regex toevoegen");
                    btnAddUitsluitRegex.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent arg0) {
                            addExcludeItem(SettingsExcludeType.REGEX);
                        }
                    });
                    pnlGeneral.add(btnAddUitsluitRegex, "cell 1 3,alignx center");
                }
                {
                    JScrollPane scrollPane = new JScrollPane();
                    pnlGeneral.add(scrollPane, "cell 1 4 2 1,grow");
                    {
                        excludeList = new JListWithImages();

                        scrollPane.setViewportView(excludeList);
                    }
                }
                {
                    JPanel pnlProxySettings = new JPanel();
                    pnlGeneral.add(pnlProxySettings, "cell 0 5 3 1,grow");
                    pnlProxySettings.setLayout(new MigLayout("", "[50px:n][][grow][grow]", "[][][][]"));
                    pnlProxySettings.add(new JLabel("Proxy Instellingen"), "cell 0 0 4 1,gapy 5");
                    pnlProxySettings.add(new JSeparator(), "cell 0 0 4 1,growx,gapy 5");
                    {
                        chkProxyserverGebruiken = new JCheckBox("Proxyserver gebruiken");
                        pnlProxySettings.add(chkProxyserverGebruiken, "cell 0 1 3 1");
                    }
                    {
                        JLabel lblProxyHost = new JLabel("Adres");
                        pnlProxySettings.add(lblProxyHost, "cell 1 2,alignx trailing");
                    }
                    {
                        txtProxyHost = new JTextField();
                        pnlProxySettings.add(txtProxyHost, "cell 2 2,growx");
                        txtProxyHost.setColumns(10);
                    }
                    {
                        JLabel lblProxyPoort = new JLabel("Poort");
                        pnlProxySettings.add(lblProxyPoort, "cell 1 3,alignx trailing");
                    }
                    {
                        txtProxyPort = new JTextField();
                        pnlProxySettings.add(txtProxyPort, "cell 2 3,growx");
                        txtProxyPort.setColumns(10);
                    }

                }
            }

            {
                pnlEpisodeLibrary = new EpisodeLibraryPanel(settingsCtrl.getSettings().getEpisodeLibrarySettings());
                tabbedPane.addTab("Serie Bibliotheek", null, pnlEpisodeLibrary, null);
            }
            {
                pnlMovieLibrary = new MovieLibraryPanel(settingsCtrl.getSettings().getMovieLibrarySettings());
                tabbedPane.addTab("Film Bibliotheek", null, pnlMovieLibrary, null);
            }
            {
                JPanel pnlOptions = new JPanel();
                tabbedPane.addTab("Opties", null, pnlOptions, null);
                pnlOptions.setLayout(new MigLayout("", "[][433px,grow][433px][100px,grow][]", "[][][][][grow][grow][][][][25px][][23px][][23px]"));
                pnlOptions.add(new JLabel("Download opties"), "cell 0 0 5 1");
                pnlOptions.add(new JSeparator(), "cell 0 0 5 1,growx");
                chkAlwaysConfirm = new JCheckBox("Controleer altijd voor het downloaden");
                pnlOptions.add(chkAlwaysConfirm, "cell 1 1 3 1,grow");
                chkAutomaticDownloadSelection = new JCheckBox("Automatische download selectie regels");
                chkAutomaticDownloadSelection.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                    }
                });
                pnlOptions.add(chkAutomaticDownloadSelection, "cell 1 2 3 1");
                {
                    JButton btnAddExtraRule = new JButton("Extra regel toevoegen");
                    btnAddExtraRule.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent arg0) {
                            addRuleRow("");
                        }
                    });
                    pnlOptions.add(btnAddExtraRule, "cell 2 3,alignx right");
                }
                JButton btnRemoveSelected = new JButton("Geselecteerde regel verwijderen");
                btnRemoveSelected.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                        removeRuleRow();
                    }
                });
                pnlOptions.add(btnRemoveSelected, "cell 3 3");
                {
                    JScrollPane scrollPane = new JScrollPane();
                    pnlOptions.add(scrollPane, "cell 2 4 2 2,grow");
                    table = new JTable();
                    scrollPane.setViewportView(table);
                }
                {
                    ArrowButton btnNaarBovenPlaatsen = new ArrowButton(SwingConstants.NORTH, 1, 10);
                    btnNaarBovenPlaatsen.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent arg0) {
                            moveRuleRowUp();
                        }
                    });
                    pnlOptions.add(btnNaarBovenPlaatsen, "cell 4 4 1 1");
                }
                {
                    ArrowButton btnNaarBenedenPlaatsen = new ArrowButton(SwingConstants.SOUTH, 1, 10);
                    btnNaarBenedenPlaatsen.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent arg0) {
                            moveRuleRowDown();
                        }
                    });
                    pnlOptions.add(btnNaarBenedenPlaatsen, "cell 4 5");
                }
                {
                    chkNoRuleMatchTakeFirst = new JCheckBox("Neem de eerste ondertitel als geen enkel regel resultaat heeft.");
                    pnlOptions.add(chkNoRuleMatchTakeFirst, "cell 2 6 3 1");
                }
                pnlOptions.add(new JLabel("Zoek opties"), "cell 0 8 5 1");
                pnlOptions.add(new JSeparator(), "cell 0 8 5 1,growx");
                chkExactMatch = new JCheckBox("Alleen exacte match");
                pnlOptions.add(chkExactMatch, "cell 1 9 3 1,grow");
                pnlOptions.add(new JLabel("Tabel opties"), "cell 0 10 5 1");
                pnlOptions.add(new JSeparator(), "cell 0 10 5 1,growx");
                chkOnlyFound = new JCheckBox("Alleen gevonden tonen");
                pnlOptions.add(chkOnlyFound, "cell 1 11 3 1,growx,aligny center");
                pnlOptions.add(new JLabel("Fout afhandeling opties"), "cell 0 12 5 1");
                pnlOptions.add(new JSeparator(), "cell 0 12 5 1,growx");
                chkStopOnSearchError = new JCheckBox("Stop zoeken na fout");
                pnlOptions.add(chkStopOnSearchError, "cell 1 13 3 1,alignx left,aligny center");
            }
        }
        {
            JPanel buttonPane = new JPanel();
            buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
            getContentPane().add(buttonPane, BorderLayout.SOUTH);
            {
                JButton okButton = new JButton(" OK ");
                okButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                        testAndSaveValues();
                    }
                });
                okButton.setActionCommand("OK");
                buttonPane.add(okButton);
                getRootPane().setDefaultButton(okButton);
            }
            {
                JButton cancelButton = new JButton("Annuleren");
                cancelButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                        setVisible(false);
                    }
                });
                cancelButton.setActionCommand("Cancel");
                buttonPane.add(cancelButton);
            }
        }
    }

    protected void moveRuleRowDown() {
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        if (table.getSelectedRow() >= 0 && table.getSelectedRow() < model.getRowCount()) {
            Object oSelected = model.getValueAt(table.getSelectedRow(), 1);
            Object oDown = model.getValueAt(table.getSelectedRow() + 1, 1);
            model.setValueAt(oSelected, table.getSelectedRow() + 1, 1);
            model.setValueAt(oDown, table.getSelectedRow(), 1);
        }
    }

    protected void moveRuleRowUp() {
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        if (table.getSelectedRow() >= 0) {
            Object oSelected = model.getValueAt(table.getSelectedRow(), 1);
            Object oUp = model.getValueAt(table.getSelectedRow() - 1, 1);
            model.setValueAt(oSelected, table.getSelectedRow() - 1, 1);
            model.setValueAt(oUp, table.getSelectedRow(), 1);
        }
    }

    private void setPreferenceSettings() {
        for (int i = 0; i < settingsCtrl.getSettings().getExcludeList().size(); i++) {
            excludeList.addItem(settingsCtrl.getSettings().getExcludeList().get(i).getType(), settingsCtrl.getSettings()
                    .getExcludeList().get(i).getDescription());
        }
        for (int i = 0; i < settingsCtrl.getSettings().getDefaultIncomingFolders().size(); i++) {
        	defaultIncomingFoldersList.addItem(SettingsExcludeType.FOLDER, settingsCtrl.getSettings()
                    .getDefaultIncomingFolders().get(i).getAbsolutePath());
        }
        chkProxyserverGebruiken.setSelected(settingsCtrl.getSettings().isGeneralProxyEnabled());
        txtProxyHost.setText(settingsCtrl.getSettings().getGeneralProxyHost());
        txtProxyPort.setText(String.valueOf(settingsCtrl.getSettings().getGeneralProxyPort()));
        chkAlwaysConfirm.setSelected(settingsCtrl.getSettings().isOptionsAlwaysConfirm());
        chkExactMatch.setSelected(settingsCtrl.getSettings().isOptionsShowExactMatch());
        chkOnlyFound.setSelected(settingsCtrl.getSettings().isOptionsShowOnlyFound());
        chkStopOnSearchError.setSelected(settingsCtrl.getSettings().isOptionsStopOnSearchError());
        pnlEpisodeLibrary.setLibrarySettings(settingsCtrl.getSettings().getEpisodeLibrarySettings());
        pnlMovieLibrary.setLibrarySettings(settingsCtrl.getSettings().getMovieLibrarySettings());
        chkAutomaticDownloadSelection.setSelected(settingsCtrl.getSettings().isOptionsAutomaticDownloadSelection());
        chkNoRuleMatchTakeFirst.setSelected(settingsCtrl.getSettings().isOptionsNoRuleMatchTakeFirst());
        for (String q : settingsCtrl.getSettings().getQualityRuleList()) {
            addRuleRow(q);
        }
    }

    protected boolean testOptionsTab() {
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        for (int i = 0; i < model.getRowCount(); i++) {
            if (model.getValueAt(i, 1).equals("") || model.getValueAt(i, 1).equals("Selecteer...")) {
                String message = "Opties: op regel " + i + 1 + " is er geen waarde geselecteerd";
                JOptionPane.showConfirmDialog(this, message,
                        "JBierSubDownloader", JOptionPane.CLOSED_OPTION,
                        JOptionPane.ERROR_MESSAGE);
                return false;
            }
        }
        return true;
    }

    protected boolean testGeneralTab() {
        try{
            Integer.parseInt(txtProxyPort.getText());
        }catch(Exception e){
            String message = "De proxy poort moet een numerische waarde zijn!";
                JOptionPane.showConfirmDialog(this, message,
                        "JBierSubDownloader", JOptionPane.CLOSED_OPTION,
                        JOptionPane.ERROR_MESSAGE);
            return false;
        }
        return true;
    }

    private void addExcludeItem(SettingsExcludeType seType) {
        if (seType == SettingsExcludeType.FOLDER){
            File path = MemoryFolderChooser.getInstance().selectDirectory(getContentPane(), "Selecteer uitsluit map");
            excludeList.addItem(seType, path.getAbsolutePath());
        } else if(seType == SettingsExcludeType.REGEX){
            String regex = JOptionPane.showInputDialog("Geef een REGEX op: (VB: S0*)");;
            excludeList.addItem(seType, regex);
        }
    }

    private void removeExcludeItem() {
        DefaultListModel<JPanel> model = (DefaultListModel<JPanel>) excludeList.getModel();
        int selected = excludeList.getSelectedIndex();
        if (model.size() > 0 && selected >= 0) {
            model.removeElementAt(selected);
        }
    }

    private void testAndSaveValues() {
        boolean status = true;
        if (testGeneralTab()) {
            ArrayList<File> folList = new ArrayList<File>();
            for (int i = 0; i < defaultIncomingFoldersList.getModel().getSize(); i++){
            	folList.add(new File(defaultIncomingFoldersList.getDescription(i)));
            }
            settingsCtrl.getSettings().setDefaultIncomingFolders(folList);
            
            ArrayList<SettingsExcludeItem> list = new ArrayList<SettingsExcludeItem>();
            for (int i = 0; i < excludeList.getModel().getSize(); i++) {
                SettingsExcludeItem sei = new SettingsExcludeItem(excludeList.getDescription(i), excludeList.getType(i));
                list.add(sei);
            }
            settingsCtrl.getSettings().setExcludeList(list);
            settingsCtrl.getSettings().setGeneralProxyEnabled(chkProxyserverGebruiken.isSelected());
            settingsCtrl.getSettings().setGeneralProxyHost(txtProxyHost.getText());
            settingsCtrl.getSettings().setGeneralProxyPort(Integer.parseInt(txtProxyPort.getText()));
        } else {
            status = false;
        }
        if (pnlEpisodeLibrary.isValidPanelValues()) {
            LibrarySettings libs = pnlEpisodeLibrary.getLibrarySettings();
            settingsCtrl.getSettings().setEpisodeLibrarySettings(libs);
        } else {
            status = false;
        }
        if (pnlMovieLibrary.isValidPanelValues()) {
            LibrarySettings libs = pnlMovieLibrary.getLibrarySettings();
            settingsCtrl.getSettings().setMovieLibrarySettings(libs);
        } else {
            status = false;
        }
        if (testOptionsTab()) {
            settingsCtrl.getSettings().setOptionsAlwaysConfirm(chkAlwaysConfirm.isSelected());
            settingsCtrl.getSettings().setOptionsShowExactMatch(chkExactMatch.isSelected());
            settingsCtrl.getSettings().setOptionsShowOnlyFound(chkOnlyFound.isSelected());
            settingsCtrl.getSettings().setOptionsStopOnSearchError(chkStopOnSearchError.isSelected());
            settingsCtrl.getSettings().setOptionsAutomaticDownloadSelection(chkAutomaticDownloadSelection.isSelected());
            settingsCtrl.getSettings().setOptionsNoRuleMatchMatchTakeFirst(chkNoRuleMatchTakeFirst.isSelected());
            DefaultTableModel model = (DefaultTableModel) table.getModel();
            ArrayList<String> list = new ArrayList<String>();
            for (int i = 0; i < model.getRowCount(); i++) {
                list.add((String) model.getValueAt(i, 1));
            }
            settingsCtrl.getSettings().setQualityRuleList(list);
        } else {
            status = false;
        }
        if (status) {
            setVisible(false);
            settingsCtrl.store();
        }
    }

}
